package com.pansoft.openplanet.widget;

import android.content.Context;
import android.content.res.TypedArray;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.SwitchCompat;
import android.text.InputFilter;
import android.util.AttributeSet;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;

import com.efounder.util.ToastUtil;
import com.efounder.utils.JfResourceUtil;
import com.pansoft.hd.model.HDException;
import com.pansoft.openplanet.R;
import com.pansoft.openplanet.constant.IPAssetsConstant;
import com.pansoft.openplanet.util.ChainParamsUtil;
import com.pansoft.openplanet.util.DecimalDigitsInputFilter;
import com.pansoft.openplanet.util.EosNetParamUtil;
import com.pansoft.openplanet.util.TCMathUtil;

import org.bitcoinj.core.Coin;
import org.web3j.utils.Convert;

import java.math.BigDecimal;
import java.math.BigInteger;

/**
 * 矿工费拖动条封装
 * Created by yqs97.
 * Date: 2019/11/20
 * Time: 11:23
 */
public class BlockChainFeeSeekBar extends LinearLayout {

    /**
     * 左上角标题文字
     */
    private String leftTopTextString;
    private int hdLeftTopTextColor;

    private LinearLayout llTopLayout;

    //显示 矿工费三个字的textview
    private TextView tvTopLeftTitle;
    //矿工费 右侧布局 start
    private LinearLayout llPredict;
    private TextView tvBlockCoinAmount;
    private TextView tvBlockCoinUnit;
    private TextView tvMoneyUnit;
    private TextView tvMoneyAmount;
    private ImageView ivArrow;
    //矿工费 右侧布局 end


    private LinearLayout llHide;
    private LinearLayout llSeekbar;
    private SeekBar seekBar;

    //承载高级选项的布局 输入框和按钮框
    private LinearLayout llAdvancedInputLayout;


//    private View viewLine2;
//    private View viewLine1;

    //高级选项中的两个输入框
    private EditText etGwei;
    private TextView tvGweiTitle;
    private EditText etGas;
    private TextView tvGasTitle;

    //承载高级选项按钮的布局
    private LinearLayout llAdbancedButton;
    //高级选项的 textview
    private TextView tvAdvancedTitle;
    //高级选项开关
    private SwitchCompat switchButton;

    //进度条变化后跟随变化的那个数字
    private TextView tvSeekbarProgress;
    //进度条变化后跟随变化的那个数字 的单位
    private TextView tvSeekbarProgressUnit;
    //推荐矿工费
    private TextView mTvRecommendGas;

    //约等于≈ 那个符号
    private TextView tvYdy;
    //是否是高级模式
    private boolean isAdvancedMode = false;

    //进度条默认开始的矿工费
    private float defaultGasPrice;
    //进度条最大的矿工费
    private float maxGasPrice;
    //进度条最小矿工费
    private float minGasPrice;

    //g默认as 数量（eth需要）
    private int defaultGasAmount;

    //当前矿工费
    private float currentGasPrice;
    //当前 燃料数量
    private int currentGasAmount;

    private int chainId;

    /**
     * btc交易的大小，默认为226
     */
    private int btcTxSize = 226;


    public BlockChainFeeSeekBar(Context context) {
        this(context, null);
    }

    public BlockChainFeeSeekBar(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public BlockChainFeeSeekBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.HdFeeSeekBar);
        leftTopTextString = typedArray.getString(R.styleable.HdFeeSeekBar_hd_left_top_text);
        hdLeftTopTextColor = typedArray.getColor(R.styleable.HdFeeSeekBar_hd_left_top_text_color, JfResourceUtil.getSkinColor(R.color.black_text_color));
        typedArray.recycle();
        initView();
        resetViewVisiable();

        //暂时隐藏法币价格显示
        hideMoneyPrice();

        //TODO 测试设置chainid
//        setChainId(IPAssetsConstant.CHAIN_ID_BTC);


    }


    private void initView() {
        inflate(getContext(), R.layout.asset_view_blockchain_fee_seekbar, this);
        llTopLayout = (LinearLayout) findViewById(R.id.ll_top_layout);
        tvTopLeftTitle = (TextView) findViewById(R.id.tv_top_left_title);
        llPredict = (LinearLayout) findViewById(R.id.ll_predict);
        tvBlockCoinAmount = (TextView) findViewById(R.id.tv_block_coin_amount);
        tvBlockCoinUnit = (TextView) findViewById(R.id.tv_block_coin_unit);
        tvMoneyUnit = (TextView) findViewById(R.id.tv_money_unit);
        tvMoneyAmount = (TextView) findViewById(R.id.tv_money_amount);
        mTvRecommendGas = (TextView) findViewById(R.id.tv_recommend_gas);
        ivArrow = (ImageView) findViewById(R.id.iv_arrow);
        llHide = (LinearLayout) findViewById(R.id.ll_hide);
        llSeekbar = (LinearLayout) findViewById(R.id.ll_seekbar_layout);
        seekBar = (SeekBar) findViewById(R.id.seek_bar);
        llAdvancedInputLayout = (LinearLayout) findViewById(R.id.ll_advanced_input);
        etGwei = (EditText) findViewById(R.id.et_gwei);
        tvGweiTitle = (TextView) findViewById(R.id.tv_gwei_title);
        etGas = (EditText) findViewById(R.id.et_gas);
        tvGasTitle = (TextView) findViewById(R.id.tv_gas_title);
//        viewLine2 = (View) findViewById(R.id.view_line2);
//        viewLine1 = (View) findViewById(R.id.view_line1);

        llAdbancedButton = (LinearLayout) findViewById(R.id.ll_adbanced_button);
        tvAdvancedTitle = (TextView) findViewById(R.id.tv_advanced_title);

        tvSeekbarProgress = (TextView) findViewById(R.id.tv_seekbar_progress);
        tvSeekbarProgressUnit = (TextView) findViewById(R.id.tv_seekbar_progress_unit);
        switchButton = (SwitchCompat) findViewById(R.id.switch_button);
        tvYdy = (TextView) findViewById(R.id.tv_ydy);

        tvTopLeftTitle.setText(leftTopTextString);
        tvTopLeftTitle.setTextColor(hdLeftTopTextColor);
        //最多输入两位小数
        etGwei.setFilters(new InputFilter[]{new DecimalDigitsInputFilter(2)});


        etGwei.setOnFocusChangeListener(new OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (!hasFocus) {
                    String text = etGwei.getText().toString();
                    try {
                        if (new BigDecimal(text).compareTo(new BigDecimal("0")) <= 0) {
                            ToastUtil.showToast(getContext(), "gwei值不能为0");
                            currentGasPrice = defaultGasPrice;
                            etGwei.setText(defaultGasPrice + "");
                            return;
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        ToastUtil.showToast(getContext(), "gwei值不合法");
                        currentGasPrice = defaultGasPrice;
                        etGwei.setText(defaultGasPrice + "");

                        return;
                    }

                    currentGasPrice = new BigDecimal(text).floatValue();
                }
                updateMinersFee(currentGasPrice);
            }
        });

        etGas.setOnFocusChangeListener(new OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (!hasFocus) {
                    String text = etGas.getText().toString();
                    try {
                        if (new BigDecimal(text).compareTo(new BigDecimal(defaultGasAmount)) == -1) {
                            ToastUtil.showToast(getContext(), "gas 值不能小于" + defaultGasAmount);
                            etGas.setText(defaultGasAmount + "");
                            currentGasAmount = defaultGasAmount;
                            return;
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        ToastUtil.showToast(getContext(), "gas值不合法");
                        etGas.setText(defaultGasAmount + "");
                        currentGasAmount = defaultGasAmount;
                        return;
                    }
                    currentGasAmount = new BigDecimal(text).intValue();
                }
                updateMinersFee(currentGasPrice);

            }
        });
        //点击事件
        llPredict.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (llHide.getVisibility() == View.VISIBLE) {
                    llHide.setVisibility(View.GONE);
                    ivArrow.setRotation(-90);
                } else {
                    llHide.setVisibility(View.VISIBLE);
                    ivArrow.setRotation(0);
                }
            }
        });

        switchButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                isAdvancedMode = isChecked;
                if (isChecked) {
                    hideSeekBar();
                    showAdvancedView();
                } else {
                    hideAdvancedView();
                    showSeekBar();
                }
            }
        });


        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
//                if (!fromUser) {
//                    return;
//                }
                currentGasPrice = getValueFromProgress(progress);
                if (chainId == IPAssetsConstant.CHAIN_ID_BTC) {
                    BigDecimal bigDecimal = new BigDecimal(currentGasPrice);
                    tvSeekbarProgress.setText(bigDecimal.intValue() + "");
                } else {
                    //格式化为两位小数显示
                    String gweiString = String.format("%.2f", currentGasPrice);
                    tvSeekbarProgress.setText(gweiString + "");
                }
                //更新计算出的矿工费
                updateMinersFee(currentGasPrice);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

        /**
         * 推荐矿工费的点击事件
         */
        mTvRecommendGas.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                setTvRecommendGas(defaultGasPrice);
            }
        });

    }

    /**
     * 更新计算出的矿工费
     *
     * @param currentGasPrice 根据进度计算出的 gwei值
     */
    private BigDecimal updateMinersFee(float currentGasPrice) {
        if (chainId == IPAssetsConstant.CHAIN_ID_BTC) {
            //固定费用
//            tvBlockCoinAmount.setText(Coin.valueOf(new BigDecimal(currentGasPrice + "").longValue()).toPlainString());
            //perByte方式
            double coinValue = TCMathUtil.mul(btcTxSize, new BigDecimal(currentGasPrice).intValue());
            tvBlockCoinAmount.setText(Coin.valueOf(new BigDecimal(coinValue + "").longValue()).toPlainString());
            //因为上面的btc 方法会返回单位btc,因此隐藏掉我们自己的
//            tvBlockCoinUnit.setVisibility(View.GONE);
        } else if (chainId == EosNetParamUtil.getEosChainId()) {


        } else {

            BigDecimal wei = Convert.toWei(currentGasPrice + "", Convert.Unit.GWEI);
            BigDecimal gasAmount = new BigDecimal(currentGasAmount);
            //估算的gas值
            BigDecimal gasEstimate = Convert.fromWei(wei.multiply(gasAmount), Convert.Unit.ETHER);
            tvBlockCoinAmount.setText(gasEstimate.toPlainString() + "");
        }

        return new BigDecimal(tvBlockCoinAmount.getText().toString());
    }

    private void hideSeekBar() {
        llSeekbar.setVisibility(View.GONE);
    }

    private void showAdvancedView() {
        llAdvancedInputLayout.setVisibility(View.VISIBLE);
        //开启高级选项后，需要将之前选中的显示出来
        etGwei.setText(currentGasPrice + "");
        //设置默认的燃料数量
        etGas.setText(defaultGasAmount + "");
    }

    private void showSeekBar() {
        llSeekbar.setVisibility(View.VISIBLE);
    }

    /**
     * 重置view 的显示隐藏状态
     */
    private void resetViewVisiable() {
        hideAdvancedView();
        llHide.setVisibility(View.GONE);
    }

    private void hideAdvancedView() {
        llAdvancedInputLayout.setVisibility(View.GONE);
        switchButton.setChecked(false);
        etGas.setText("");
        etGwei.setText("");
    }

    /**
     * 因为暂时不知道汇率所以隐藏法币价格
     */
    private void hideMoneyPrice() {
        tvMoneyUnit.setVisibility(View.GONE);
        tvMoneyUnit.setVisibility(View.GONE);
        tvYdy.setVisibility(View.GONE);
    }

    /**
     * 根据最小最大的gas值获取 seekbar的最大进度
     *
     * @param maxGasPrice
     * @param minGasPrice
     * @return
     */
    private int getMaxProgress(float maxGasPrice, float minGasPrice) {
        BigDecimal differenceDecimal = new BigDecimal(maxGasPrice + "").subtract(new BigDecimal(minGasPrice + ""));
        BigDecimal maxProgress = differenceDecimal.multiply(new BigDecimal("100"));
        return maxProgress.intValue();
    }

    /**
     * 将进度值转换为 gas值
     *
     * @param progress
     * @return
     */
    private float getValueFromProgress(int progress) {
        BigDecimal differenceDecimal = new BigDecimal(maxGasPrice + "").subtract(new BigDecimal(minGasPrice + ""));
        BigDecimal per = differenceDecimal.divide(new BigDecimal(getMaxProgress(maxGasPrice, minGasPrice)));
        BigDecimal value = per.multiply(new BigDecimal(progress + ""));
        return new BigDecimal(minGasPrice + "").add(value).floatValue();
    }

    /**
     * 将gas值转换为 progress进度值
     *
     * @param value
     * @return
     */
    private int getProgressFromValue(float value) {
        BigDecimal differenceDecimal = new BigDecimal(maxGasPrice + "").subtract(new BigDecimal(minGasPrice + ""));
        BigDecimal per = differenceDecimal.divide(new BigDecimal(getMaxProgress(maxGasPrice, minGasPrice)));
        BigDecimal differenceDecimal2 = new BigDecimal(value + "").subtract(new BigDecimal(minGasPrice));
        return differenceDecimal2.divide(per).intValue();
    }


    //TODO 对外提供的操作方法

    public void setBlockCoinUnit(String unit) {
        tvBlockCoinUnit.setText(unit);
    }

    public void setMoneyUnit(String unit) {
        tvMoneyUnit.setText(unit);
    }

    public SeekBar getSeekBar() {
        return seekBar;
    }

    /**
     * 获取滑动数值的手续费
     *
     * @return
     */
    public String getProgressGas() {
        etGwei.clearFocus();
        etGas.clearFocus();
        if (!isAdvancedMode) {
            return tvSeekbarProgress.getText().toString();
        } else {
            return new BigDecimal(etGwei.getText().toString()).toPlainString();
        }
    }

    /**
     * 获取手续费换算的值（换算成eth pwr btc 等）
     *
     * @return
     */
    public String getGasConversion() {
        return updateMinersFee(currentGasPrice).toPlainString();
    }

    public BigInteger getGasAmount() {
        etGwei.clearFocus();
        etGas.clearFocus();
        if (!isAdvancedMode) {
            //eth 默认 时21000 pwr 有时候是22396
            return new BigInteger(currentGasAmount + "");
        } else {
            //不能小于两万1
            return new BigInteger(etGas.getText().toString());
        }
    }


    /**
     * 设置矿工费那个标题
     *
     * @param title
     */
    public void setTopLeftTitle(String title) {
        tvTopLeftTitle.setText(title);
    }

    /**
     * 设置chainid 很重要
     *
     * @param chainId
     */
    public void setChainId(int chainId) {
        this.chainId = chainId;


        //---- 设置一些货币单位符号等
        IPAssetsConstant.ChainEnum chainEnum = IPAssetsConstant.ChainEnum.getChainEnumByChainId(chainId);
        //设置交易手续费单位
        String gasUnit = ChainParamsUtil.getGasUnitByChainId(chainId);
        tvSeekbarProgressUnit.setText(gasUnit);
        //设置区块链货币单位
        tvBlockCoinUnit.setText(ChainParamsUtil.getAssetUnitByChainId(chainId));

        //设置计算的手续费默认为0
        tvBlockCoinAmount.setText("0");

        //如果是btc 或者eos ，隐藏高级选项
        if (chainId == IPAssetsConstant.CHAIN_ID_BTC || chainId == IPAssetsConstant.CHAIN_ID_EOS) {
            llAdvancedInputLayout.setVisibility(View.GONE);
            llAdbancedButton.setVisibility(View.GONE);
        }


        setDefaultParams(chainId);
    }

    /**
     * 设置btc交易的size大小
     */
    public void setBtcTxSize(int size) {
        btcTxSize = size;
        updateMinersFee(currentGasPrice);
    }


    /**
     * 根据chainid 设置默认值，这些默认值以后可以修改
     *
     * @param chainId
     */
    private void setDefaultParams(int chainId) {
        if (chainId == IPAssetsConstant.CHAIN_ID_BTC) {
            //单位btc的聪/byte, sat/byte
            minGasPrice = 1f;
            maxGasPrice = 300f;
            defaultGasPrice = 25f;

        } else if (chainId == EosNetParamUtil.getEosChainId()) {
            //eos 随便乱写的，使用的时候需要修改
            minGasPrice = 1f;
            maxGasPrice = 100f;
            defaultGasPrice = 10f;

        } else {
            //单位gwei
            minGasPrice = 1.5f;
            maxGasPrice = 100f;
            defaultGasPrice = 12f;
            defaultGasAmount = 21000;
        }

        //当前显示的数值 设置为默认值
        currentGasAmount = defaultGasAmount;
        currentGasPrice = defaultGasPrice;

        int max = getMaxProgress(maxGasPrice, minGasPrice);
        seekBar.setMax(max);
        int defaultProgress = getProgressFromValue(defaultGasPrice);
        seekBar.setProgress(defaultProgress);

        //更新矿工费计算转换
        updateMinersFee(currentGasPrice);


    }

    /**
     * 设置默认最少使用的gas 的数量，必须大于21000
     *
     * @param defaultGasAmount
     */
    public void setDefaultGasAmount(int defaultGasAmount) {
        if (defaultGasAmount < 21000) {
            throw new HDException("defaultGasAmount 不能小于21000");
        }
        this.defaultGasAmount = defaultGasAmount;
        currentGasAmount = defaultGasAmount;
        //更新预估的矿工费
        updateMinersFee(Float.valueOf(getProgressGas()));
    }

    /**
     * 显示推荐矿工费按钮并设置数量
     */
    public void setTvRecommendGas(float gas){
        defaultGasPrice = gas;
       int progress =  getProgressFromValue(gas);

        if(mTvRecommendGas!=null){
            mTvRecommendGas.setVisibility(VISIBLE);
        }

       if(seekBar!=null){
           seekBar.setProgress(progress);
       }
       updateMinersFee(gas);

    }


    /**
     * 隐藏推荐矿工费按钮
     */
    public void hideTvRecommendGas(){
        if(mTvRecommendGas!=null){
            mTvRecommendGas.setVisibility(GONE);
        }
    }

    public interface onSeekBarChangeListener {

        String a();

    }
}
